package com.hisicom.scqxspxcjc.interfaces;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.util.DigestUtils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @author zhonggls
 * @date 2023/10/23 10:17
 * @Explain
 */
public class SignTool {
    static private String salt = "B0656AFF722297FCA94191EE31B06182";//	Qxsp@123 md5加密

    //参数封装
    public static String reqTool(Object object) {
        JSONObject jsonObject = new JSONObject();
        JSONObject head = new JSONObject();
        JSONObject body = new JSONObject();
        if (object == null) {
            body.put("createTime", new Date().getTime());
        } else if (object instanceof List) {
            JSONArray jsonArray = (JSONArray) JSONObject.toJSON(object);
            body.put("list", jsonArray);
            body.put("createTime", new Date().getTime());
        } else {
            body = (JSONObject) JSONObject.toJSON(object);
        }
        String sign = CtripeEncryption(body, salt);
        head.put("sign", sign);
        jsonObject.put("head", head);
        jsonObject.put("body", body);
        return jsonObject.toJSONString();
    }

    /**
     * 验证密码
     *
     * @param jsonObject
     * @return
     */
    public static Boolean verification(JSONObject jsonObject) {
        JSONObject headJson = jsonObject.getJSONObject("head");
        JSONObject bodyJson = jsonObject.getJSONObject("body");
        String reqSign = headJson.getString("sign");
        // 系统生成的密钥
        String sign = CtripeEncryption(bodyJson, salt);
        return reqSign.equals(sign);
    }

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("q", "1");
        map.put("w", "2");
        List list = new ArrayList();
        list.add(map);
        list.add(map);
        list.add(map);
        String dd = reqTool(list);
        System.out.println(dd);
        JSONObject jsonObject = JSON.parseObject(dd);
        System.out.println("秘钥" + verification(jsonObject));
    }

    /**
     * 器械审批系统加密规则
     * 1. 器械审批系统约定一个唯一的 CooperationSecret。
     * 2. 将请求参数里面的 body 节点下的所有属性按字母先后顺序排序
     * key + value .... key + value 。
     * a) 排序若首字母相同，则对第二个字母进行排序，以此类推。
     * b) value 无需编码，数组直接按顺序拼接，无需排序。
     * c) 如果某个字段是字符串，只有是 null 的时候才不会参加签名，空字符串会被计入签名。
     * 3. 将约定的密钥（CooperationSecret）同时拼接到参数字符串头、尾部，再转化成大写，再进行 md5Hex 加密，格式是：
     * md5(CooperationSecretkey1value1key2value2..CooperationSecret)。
     */
    public static String CtripeEncryption(JSONObject jsonObject, String salt) {

        if (jsonObject == null) {
            return "";
        }
        Map<String, String> treeMap = new TreeMap();
        Set<String> strings = jsonObject.keySet();
        int i = strings.size();
        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            String value = trimString(jsonObject.get(next) + "", "[\"", "\"]");
            try {
                String string = jsonObject.get(next) + "";
                List<TreeMap<String, Object>> maps = JSON.parseObject(string, new TypeReference<List<TreeMap<String, Object>>>() {
                });
                String string1 = maps.toString();
                value = string1.replace("=", "").replace(",", "").replace("[{", "").replace("}]", "").replace(" ", "").replace("{", "").replace("}", "");
            } catch (Exception e) {
//                log.info(jsonObject.get(next)+"解析，不是List类型");
            }
            treeMap.put(next, value);
        }
        Set<Map.Entry<String, String>> entries = treeMap.entrySet();
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> n : entries) {
            sb.append(n.getKey() + n.getValue());
        }
        String key = (salt + sb + salt).toUpperCase();
        String s = SMD5(key);
        System.out.println(s);
        return s;
    }

    private static String trimString(String str, String delStr, String endStr) {
        int delStrLength = delStr.length();
        if (str.startsWith(delStr)) {
            str = str.substring(delStrLength);
        }
        int endStrLength = endStr.length();
        if (str.endsWith(endStr)) {
            str = str.substring(0, str.length() - endStrLength);
        }
        return str;
    }

    public static String SMD5(String inStr) {
        return DigestUtils.md5DigestAsHex(inStr.getBytes());
    }

    public static String sha1(String input) {
        try {
            // 创建MessageDigest对象
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            // 提供要加密的数据
            md.update(input.getBytes());
            // 生成SHA1摘要
            byte[] digest = md.digest();
            // 将摘要转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            String sha1Hex = sb.toString();
            return sha1Hex;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}
